package com.eedi.framework.sms.service;

import com.aliyuncs.utils.StringUtils;
import com.eedi.framework.common.enums.CommonStatusEnum;
import com.eedi.framework.common.exception.ServerException;
import com.eedi.framework.common.exception.util.ServiceExceptionUtil;
import com.eedi.framework.common.pojo.PageResult;
import com.eedi.framework.common.util.collection.CollectionUtils;
import com.eedi.framework.common.util.object.BeanUtils;
import com.eedi.framework.sms.controller.sys.vo.SysSmsPageReq;
import com.eedi.framework.sms.controller.sys.vo.SysSmsResp;
import com.eedi.framework.sms.controller.sys.vo.SysSmsSaveReq;
import com.eedi.framework.sms.controller.sys.vo.template.SysSmsTemplatePageReq;
import com.eedi.framework.sms.dal.dataobject.SysSmsDO;
import com.eedi.framework.sms.dal.dataobject.SysSmsTemplateDO;
import com.eedi.framework.sms.dal.mapper.SmsMapper;
import com.eedi.framework.sms.enums.SmsNotifyOptionalEnum;
import com.eedi.framework.sms.enums.SmsSceneEnum;
import com.eedi.framework.sms.enums.SysSmsErrorCodeConstants;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.eedi.framework.common.exception.util.ServiceExceptionUtil.exception;

/**
 * 短信 Service 实现类
 *
 * @author 永聚长青源码
 */
@Service
@Validated
public class SmsServiceImpl implements SmsService {

    @Resource
    private SmsMapper smsMapper;
    @Resource
    private SmsTemplateService smsTemplateService;

    @Override
    public String createSms(SysSmsSaveReq createReqVO) {
        // 插入
        SysSmsDO sms = BeanUtils.toBean(createReqVO, SysSmsDO.class);
        smsMapper.insert(sms);
        // 返回
        return sms.getSysSmsId();
    }

    @Override
    public void updateSms(SysSmsSaveReq updateReqVO) {
        // 校验存在
        validateSmsExists(updateReqVO.getSysSmsId());
        // 更新
        SysSmsDO updateObj = BeanUtils.toBean(updateReqVO, SysSmsDO.class);
        smsMapper.updateById(updateObj);
    }

    @Override
    public void deleteSms(String systemSmsId) {
        // 校验存在
        validateSmsExists(systemSmsId);
        // 删除
        smsMapper.deleteById(systemSmsId);
    }

    private void validateSmsExists(String systemSmsId) {
        if (smsMapper.selectById(systemSmsId) == null) {
            throw ServiceExceptionUtil.exception(SysSmsErrorCodeConstants.SYS_SMS_NOT_EXISTS);
        }
    }

    @Override
    public SysSmsDO getSms(String systemSmsId) {
        return smsMapper.selectById(systemSmsId);
    }

    @Override
    public PageResult<SysSmsResp> getSmsPage(SysSmsPageReq pageReqVO) {
        //查询所有开启状态的公众号消息模板
        SysSmsTemplatePageReq reqVO = new SysSmsTemplatePageReq();
        reqVO.setPageNo(pageReqVO.getPageNo());
        reqVO.setPageSize(pageReqVO.getPageSize());
        reqVO.setSysSmsTemplateStatus(CommonStatusEnum.ENABLE);
        reqVO.setSysSmsTemplateClientType(pageReqVO.getSysSmsTemplateClientType());
        PageResult<SysSmsTemplateDO> smsTemplatePageResult = smsTemplateService.getSmsTemplatePage(reqVO);
        if (CollectionUtils.isAnyEmpty(smsTemplatePageResult.getList())) {
            return PageResult.empty();
        }
        PageResult<SysSmsResp> pageResult = BeanUtils.toBean(smsTemplatePageResult, SysSmsResp.class);
        List<String> templateIds = smsTemplatePageResult.getList().stream().map(SysSmsTemplateDO::getSysSmsTemplateId).collect(Collectors.toList());
        List<SysSmsDO> sysSmsDOList = smsMapper.selectListByTemplateIds(templateIds);
        Map<String, SysSmsDO> smsMap = sysSmsDOList.stream().collect(Collectors.toMap(SysSmsDO::getSysSmsTemplateId, x -> x));
        //可选的短信发送模式从每个系统取
        pageResult.getList().stream().filter(x-> SmsNotifyOptionalEnum.OPTIONAL.equals(x.getSysSmsTemplateNotifyOptional())).forEach(sms -> {
            SysSmsDO sysSmsDO = smsMap.get(sms.getSysSmsTemplateId());
            sms.setSysSmsTemplateStatus(sysSmsDO != null ? sysSmsDO.getSysSmsStatus() : CommonStatusEnum.DISABLE);
            sms.setSysSmsId(sysSmsDO != null ? sysSmsDO.getSysSmsId() : null);
        });
        return pageResult;
    }

    @Override
    public void updateSmsStatus(String systemSmsId, String systemSmsTemplateId, CommonStatusEnum status) {
        if (StringUtils.isEmpty(systemSmsId) && StringUtils.isEmpty(systemSmsTemplateId)) {
            throw new ServerException(SysSmsErrorCodeConstants.SYS_SMS_MSG_OR_TEMPLATE_ID_PARAM_ALL_EMPTY);
        }
        if (!StringUtils.isEmpty(systemSmsId)) {
            //短信消息配置已存在
            validateSmsExists(systemSmsId);
            SysSmsDO update = new SysSmsDO();
            update.setSysSmsId(systemSmsId);
            update.setSysSmsStatus(status);
            smsMapper.updateById(update);
            return;
        }

        //短信消息配置不存在，需要初始化
        SysSmsTemplateDO templateDO = smsTemplateService.getSmsTemplate(systemSmsTemplateId);
        if (templateDO == null) {
            throw ServiceExceptionUtil.exception(SysSmsErrorCodeConstants.SYS_SMS_TEMPLATE_NOT_EXISTS);
        }
        if(SmsNotifyOptionalEnum.MUST.equals(templateDO.getSysSmsTemplateNotifyOptional())){
            throw ServiceExceptionUtil.exception(SysSmsErrorCodeConstants.SYS_SMS_TEMPLATE_MUST_AVOID_UPDATE);
        }
        SysSmsDO sysSmsDO = new SysSmsDO();
        sysSmsDO.setSysSmsTemplateId(templateDO.getSysSmsTemplateId());
        sysSmsDO.setSysSmsStatus(status);
        smsMapper.insert(sysSmsDO);
    }

    @Override
    public boolean isSendSms(SmsSceneEnum smsScene) {
        SysSmsTemplateDO smsTemplate = smsTemplateService.getSmsTemplate(smsScene);
        if (smsTemplate == null) {
            throw ServiceExceptionUtil.exception(SysSmsErrorCodeConstants.SYS_SMS_TEMPLATE_NOT_EXISTS);
        }
        if (SmsNotifyOptionalEnum.MUST.equals(smsTemplate.getSysSmsTemplateNotifyOptional())) {
            return Boolean.TRUE;
        }
        List<SysSmsDO> sysSmsDOList = smsMapper.selectListByTemplateIds(Collections.singletonList(smsTemplate.getSysSmsTemplateId()));
        if(CollectionUtils.isAnyEmpty(sysSmsDOList)){
            return Boolean.FALSE;
        }
        return CommonStatusEnum.ENABLE.equals(sysSmsDOList.get(0).getSysSmsStatus());
    }

}
